In diesem Kurs wird mit der Sprache R gearbeitet. R wird bereits mit einer rudimentären grafischen Benutzer:innenoberfläche geliefert. Ich rate deutlich davon ab, sich auf diese zu beschränken. Durch das Nutzen von RStudio wird das Arbeiten mit R deutlich Benutzer:innenfreundlicher.
- R Installieren https://cran.r-project.org/ aufrufen Betriebssystem wählen Neuste R Version downloaden und installieren
- RStudio installieren https://www.rstudio.com/products/rstudio/download/#download aufrufen Free version auswählen Betriebssystem auswählen RStudio installieren
Es ist möglich jegliche Berechnung, die in einem Taschenrechner möglich sind auch in r auszuführen.
1+2
## [1] 3
1-2
## [1] -1
2*2
## [1] 4
6/2
## [1] 3
2^2
## [1] 4
Auf diese Ergebnisse lässt sich jedoch nicht zugreifen, da sie nicht gespeichert wurden. Durch <- werden Berechnungen einem Objekt zugeordnet und dieses ggf. erstellt. Mit diesen Objekten können dann weiter Berechnungen durchgeführt werden.
a <- 3*5
a
## [1] 15
b <- 4-2
a* b
## [1] 30
Die erstellten Objekte sind veränderlich.
a <- a* b -6 + (2*4)
a
## [1] 32
In der Praxis wird empfohlen, den Objekten aussagekräftige Namen zu geben. Sodass, auch bei späteren Betrachtungen, der Code verständlich bleibt. Da zwischen Groß- und Kleinschreibung unterschieden wird, empfehle ich nur Kleinschreibung zu verwenden, um Verwirrungen zu vermeiden. Den die Objekte Mittelwert und mittelwert sind zwei verschiedene Objekte.
mittelwert <- (1+2+3+4+5+6)/6
Mittwelwert <- (5+6+7+8) / 4
Führt man eine Operation öfter durch, ist es manchmal sinnvolle eine Funktion im Vorhinein zu definieren, um dann später darauf zuzugreifen.
word_printer <- function(word){
print(paste('Dies ist ein Wort:', word ))
}
word_printer('hallo')
## [1] "Dies ist ein Wort: hallo"
Objekte können verschiedenen Klassen angehören. Nicht mit jeder Klasse lässt sich jeder Befehl ausführen. Dies ist auch sinnvoll, da in der Ursprungsform das Rechen mit Buchstaben nicht möglich ist.
text <- "Mittwoch ist Spritwoch"
class(text)
## [1] "character"
zahl <- 1
class(zahl)
## [1] "numeric"
zahl <- "1"
class(zahl)
## [1] "character"
zahl <- 1.1
class(zahl)
## [1] "numeric"
date <- as.Date("2020-05-05")
class(date)
## [1] "Date"
x <- "apfel" == "birnen"
x
## [1] FALSE
class(x)
## [1] "logical"
Objekte können jedoch auch mehrere Werte enthalten. Um verschiedene Möglichkeiten der Komplexität zu haben, gibt es verschiedene Datenstrukturen. Bei Vektoren handelt es sich um eindimensionale Reihen von Ausprägungen (aus der Schule bekannt). Die Klasse der Ausprägungen müssen jedoch gleich bleiben sein. Eine Liste hingegen kann verschieden Klassen enthalten. In zwei Dimensionen entspricht der Vektor der Matrix und das Dataframe der Liste. Dataframes können auch mehr als zwei Auf Twitter teilenDimensionen haben, werden jedoch dann Tensor genannt. Auf Ausprägungen in jeder Datenstruktur kann auch einzeln zugegriffen werden.
vektor_zahlen <- c(1,2,3,4,5)
vektor_zahlen
## [1] 1 2 3 4 5
vektor_text <- c("Dumbledore", "Rubeus Hagrid", "Minerva McGonagall")
vektor_text
## [1] "Dumbledore" "Rubeus Hagrid" "Minerva McGonagall"
vektor_text[1]
## [1] "Dumbledore"
vektor_text[c(1,2)]
## [1] "Dumbledore" "Rubeus Hagrid"
Mit Vektoren können auch Berechnungen durchgeführt werden bzw. die Vektoren als Input in Funktionen gegeben werden. Praktische Funktionen für Vektoren sind beispielsweise mean(), length(), sum() und sd(). Informationen über Funktionen aus Paketen können über ?mean() aufegrufen werden.
vektor_zahlen_2 <- c(8,9,0,23,3)
vektor_zahlen * vektor_zahlen_2
## [1] 8 18 0 92 15
mean(vektor_zahlen)
## [1] 3
length(vektor_zahlen * vektor_zahlen_2)
## [1] 5
sum(vektor_zahlen * vektor_zahlen_2)
## [1] 133
sd(vektor_zahlen_2)
## [1] 8.848729
Listen können verschiedene Klassen von Daten enthalten. Beispielsweise ist die Kombination von character und numeric Klasse möglich. Grundsätzlich können Listen verschiedenste Formate enthalten, z. B. zum Beispiel auch Vektoren oder sogar auch andere Listen. Wenn den Variablen Namen zugewiesen werden, kann auf diese über die $ Option direkt auf die Variabel zugegriffen werden. Wie bereits zuvor ist das Zugreifen über die [] ebenfalls möglich.
mitarbeiter <- list(name = "Dumbledore", "Rubeus Hagrid", "Minerva McGonagall", ort ="hogwarts", Land = "uk", postleitzahl = 48151 )
mitarbeiter
## $name
## [1] "Dumbledore"
##
## [[2]]
## [1] "Rubeus Hagrid"
##
## [[3]]
## [1] "Minerva McGonagall"
##
## $ort
## [1] "hogwarts"
##
## $Land
## [1] "uk"
##
## $postleitzahl
## [1] 48151
mitarbeiter$name
## [1] "Dumbledore"
mitarbeiter[1]
## $name
## [1] "Dumbledore"
mitarbeiter[[2]]
## [1] "Rubeus Hagrid"
mitarbeiter[2]
## [[1]]
## [1] "Rubeus Hagrid"
Bei Matrizen handelt es um die zweidimensionale äquivalent zum Vektor. Ein zugreifen über den $ Operator ist nicht möglich. Jedoch weiterhin über die []. Wobei die [,1] der ersten Spalte und [1, ] der ersten Zeile entspricht. [2,1] ist dann die erste Zelle in der ersten Spalte in der zweiten Zeile.
x <- 1:9
m <- matrix(x, nrow = 3)
m
## [,1] [,2] [,3]
## [1,] 1 4 7
## [2,] 2 5 8
## [3,] 3 6 9
colnames(m) <- c("eins", "zwei", "drei")
rownames(m)<- c("eins", "zwei", "drei")
m
## eins zwei drei
## eins 1 4 7
## zwei 2 5 8
## drei 3 6 9
m[,2]
## eins zwei drei
## 4 5 6
Bei Dataframes handelt es sich um das meist genutzten Datenformat. Wie bei den Listen kann auf Dataframes direkt auf die Spalten/Variablen über $ zugegriffen werden. Auch können verschiedene Klassen gespeichert werden.
hogwarts_mitarbeiter <- data.frame(
name = c("Dumbledore", "Rubeus Hagrid", "Minerva McGonagall", "Severus Snape"),
beruf = c("Schulleiter", "Wildhüter", "Lehrer_in", "Lehrer_in"),
alter = c(102, 54, 65, 55)
)
hogwarts_mitarbeiter
## name beruf alter
## 1 Dumbledore Schulleiter 102
## 2 Rubeus Hagrid Wildhüter 54
## 3 Minerva McGonagall Lehrer_in 65
## 4 Severus Snape Lehrer_in 55
hogwarts_mitarbeiter[2,2]
## [1] "Wildhüter"
hogwarts_mitarbeiter[2,1:3]
## name beruf alter
## 2 Rubeus Hagrid Wildhüter 54
hogwarts_mitarbeiter$name
## [1] "Dumbledore" "Rubeus Hagrid" "Minerva McGonagall"
## [4] "Severus Snape"
hogwarts_mitarbeiter$beruf[1]
## [1] "Schulleiter"
Grundsätzlich ist es empfehlenswert, zu Beginn einer Analyse eine Übersicht über die Daten zu erhalten. Dies ist z. B. durch die Funktion str() zu erreichen. Für jede Variabel wird die Klasse und die ersten Ausprägungen dargestellt.
str(hogwarts_mitarbeiter)
## 'data.frame': 4 obs. of 3 variables:
## $ name : chr "Dumbledore" "Rubeus Hagrid" "Minerva McGonagall" "Severus Snape"
## $ beruf: chr "Schulleiter" "Wildhüter" "Lehrer_in" "Lehrer_in"
## $ alter: num 102 54 65 55
Eine weitere praktische Funktion um einen Überblick zu erhalten ist die Funktion Summary(). Auch hier erhält, wird die Klasse pro Variable dargestellt. Für numerische Variablen erhält man weiterhin Informationen über die Verteilung.
summary(hogwarts_mitarbeiter)
## name beruf alter
## Length:4 Length:4 Min. : 54.00
## Class :character Class :character 1st Qu.: 54.75
## Mode :character Mode :character Median : 60.00
## Mean : 69.00
## 3rd Qu.: 74.25
## Max. :102.00
Durch head() ist es möglich nur eine gewisse Anzahl von Zeilen auszugeben.
head(hogwarts_mitarbeiter,5)
## name beruf alter
## 1 Dumbledore Schulleiter 102
## 2 Rubeus Hagrid Wildhüter 54
## 3 Minerva McGonagall Lehrer_in 65
## 4 Severus Snape Lehrer_in 55
Die Funktion mean() in Kombination mit der Auswahl einer numerischen Variable bestimmt den Durchschnitt
mean(hogwarts_mitarbeiter$alter)
## [1] 69
Durch Subset() können Dataframes in Base r gefiltert werden. In diesem Beispiel werden alle Zeilen ausgeben, in denen der Name nicht Dumbledore ist.
subset(hogwarts_mitarbeiter, name != "Dumbledore")
## name beruf alter
## 2 Rubeus Hagrid Wildhüter 54
## 3 Minerva McGonagall Lehrer_in 65
## 4 Severus Snape Lehrer_in 55
Bereits Base R bietet viele Funktionen und Möglichkeiten. Die besondere Power von R kommt jedoch durch die hohe Anzahl an verschieden Packages, die den Funktionsumfang deutlich erweitern. Packages können von jeden erstellt werden. Bevor diese jedoch über CRAN (install.packages) heruntergeladen werden können, hat eine andere freiwillige Person dieses überprüft. Packages können auch abseits von CRAN installiert werden. Hier ist jedoch Vorsicht geboten, da unklar sein kann, was dieses Paket enthält (Viren).
install.packages("tidyverse")
library()
Packages müssen nur einmal in dem entsprechenden Environment installiert werden. Bevor das Packages jedoch nutzbar ist, muss es pro Session per library(tidyverse) aktiviert werden.
library(tidyverse)
Tidyverse bietet viele verschiedene Funktionen zum Arbeiten mit Daten. Neben diesen Funktionen kommt mit Tidyverse auch die Möglichkeit einer anderen Syntax -Konzept zu nutzen. Hierbei spielt der Pipe-Operatur %>% die entscheidende Rolle. Durch %>% können Argumente und Daten auf einfache Weise an die nächste Funktion übergeben werden und erleichter deutlich das Arbeiten und Lesen von RCode. Durch %>% werden hier beispielsweise die daten aus dem Dataframe an die Funktion filter übergeben. DieDaten werden auf alle Zeilen gefiltert, die in der Variable name die Ausprägung Dumbledore haben.
hogwarts_mitarbeiter %>% filter( name == "Dumbledore")
## name beruf alter
## 1 Dumbledore Schulleiter 102
Durch die Funktion group_by werden die Daten anhand des Inputs gruppiert. Group_by erfordert eine weitere Funktion, in der die Berechnungsart pro Gruppe definiert werden muss. Hier gibt es unzählige Möglichkeiten. In diesem Beispiel wird die Anzahl der Ausprägungen pro Gruppe gezählt.
hogwarts_mitarbeiter %>% group_by(beruf) %>% count()
## # A tibble: 3 x 2
## # Groups: beruf [3]
## beruf n
## <chr> <int>
## 1 Lehrer_in 2
## 2 Schulleiter 1
## 3 Wildhüter 1
Besonders mächtig in Kombination mit Group_by ist die Funktion summarise. In dieser Funktion kann die Operation, die pro Gruppe durchgeführt wird, manuell definiert werden. In diesem Beispiel wird für jede Gruppe der gruppenspezifische Mittelwert berechnet.
hogwarts_mitarbeiter %>% group_by(beruf) %>% summarise(d_alter = mean(alter))
## # A tibble: 3 x 2
## beruf d_alter
## <chr> <dbl>
## 1 Lehrer_in 60
## 2 Schulleiter 102
## 3 Wildhüter 54
In For-Loops wird über ein zu definierendes Element iteriert. So kann für jedes beispielsweise für jede Zeile in einem Dataframe eine Berechnung durchgeführt werden.
for (i in 1:10){
print(i)
}
## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 5
## [1] 6
## [1] 7
## [1] 8
## [1] 9
## [1] 10
In einem While-Loop wird die Funktion innerhalb des Loops so lange iterativ durchgeführt, bis die in While definierte Bedingung nicht mehr erfüllt ist.
i <- 1
while (i < 6) {
print(i)
i = i+1
}
## [1] 1
## [1] 2
## [1] 3
## [1] 4
## [1] 5
#Laden Library
library(plotly)
library(dplyr)
library(jsonlite)
# Laden der Bundestag Daten
filename <- file.choose()
Bundestag <- readRDS(filename)
# Erste fünf Zeilen sehen
#View(head(Bundestag))
# Ãueberblick
str(Bundestag)
## 'data.frame': 379545 obs. of 11 variables:
## $ date : chr "1991-03-12" "1991-03-12" "1991-03-12" "1991-03-12" ...
## $ agenda : chr NA NA NA NA ...
## $ speechnumber : chr "2" "3" "4" "5" ...
## $ speaker : chr "Theodor Waigel" "Rita Süssmuth" "Theodor Waigel" "Rita Süssmuth" ...
## $ party : chr "CDU/CSU" "CDU/CSU" "CDU/CSU" "CDU/CSU" ...
## $ party.facts.id: num 211 211 211 211 86 211 211 211 383 211 ...
## $ chair : logi FALSE TRUE FALSE TRUE FALSE TRUE ...
## $ terms : num 880 15 5756 69 233 ...
## $ text : chr "Frau Präsidentin ! Meine sehr geehrten Damen und Herren ! Der Ihnen heute zur ersten Beratung vorliegende Entwu"| __truncated__ "Herr Duve , ich fordere Sie auf , Herrn Waigel reden zu lassen . ." "Nicht viel besser sieht es im Straßenwesen aus . Auch das früher vorbildliche S- und U-Bahn-System Berlins ist "| __truncated__ "Meine Damen und Herren , wie bereits heute morgen mitgeteilt , kommen wir jetzt zur Beratung und Abstimmung übe"| __truncated__ ...
## $ parliament : chr "DE-Bundestag" "DE-Bundestag" "DE-Bundestag" "DE-Bundestag" ...
## $ iso3country : chr "DEU" "DEU" "DEU" "DEU" ...
summary(Bundestag)
## date agenda speechnumber speaker
## Length:379545 Length:379545 Length:379545 Length:379545
## Class :character Class :character Class :character Class :character
## Mode :character Mode :character Mode :character Mode :character
##
##
##
##
## party party.facts.id chair terms
## Length:379545 Min. : 86.0 Mode :logical Min. : 1.0
## Class :character 1st Qu.: 211.0 FALSE:212460 1st Qu.: 11.0
## Mode :character Median : 383.0 TRUE :167085 Median : 57.0
## Mean : 607.8 Mean : 290.5
## 3rd Qu.: 573.0 3rd Qu.: 406.0
## Max. :1976.0 Max. :17202.0
## NA's :71981
## text parliament iso3country
## Length:379545 Length:379545 Length:379545
## Class :character Class :character Class :character
## Mode :character Mode :character Mode :character
##
##
##
##
# Filtern der Daten nach Partein. Anschliessend nach Parteien gruppieren und die Anzahl der Reden zählen
party_speech <- Bundestag %>% filter(party != 'NA' & date >= '2017-01-01' ) %>% group_by(party) %>% count()
# Definieren der Farben - Parteifarben
colors <- c('rgb(139,69,19)', 'rgb(0,0,0)', 'rgb(255,237,0)', 'rgb(100,161,45)', 'rgb(255, 255, 255)', 'rgb(104,34,139)' ,'rgb(227, 0, 15)')
# Plotly
fig <- plot_ly(party_speech, labels = ~party, values = ~n, type = 'pie',
textposition = 'inside',
textinfo = 'label+percent',
insidetextfont = list(color = '#FFFFFF'),
hoverinfo = 'text',
text = ~paste( n, ' Reden'),
marker = list(colors = colors,
line = list(color = '#FFFFFF', width = 1)),
showlegend = FALSE)
# Layout
fig <- fig %>% layout(title = 'Verteilung der Reden nach Partei seit 2017',
xaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE),
yaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE))
# Ausführen
fig
setwd('C:\\Users\\Drecker\\Documents\\Lehre')
# load data
kreml <- lapply(readLines(".\\Daten\\kremlin_transcripts_en_2021_03_01.json"), fromJSON)
# Umwandeln von List in List zu dataframe
kreml_data <- data.frame(id = as.integer(), date = as.character(), title = as.character(), text = as.character())
for (i in 1:length(kreml)){
doc <- data.frame(id = kreml[[i]]$`_source`$kremlin_id, date = kreml[[i]]$`_source`$date, title = kreml[[i]]$`_source`$title, text = kreml[[i]]$`_source`$transcript)
kreml_data <- bind_rows(kreml_data, doc )
}
# Erstellen einer Day Spalte
kreml_data <- kreml_data %>% mutate(weekday = weekdays(as.Date(kreml_data$date)) )
# Group by weekday
plot_data <-kreml_data %>%
group_by(weekday) %>%
count()
# Ãndern des weekdays auf factor um anschlieÃssend die Tage ordnen zu können
# Wenn dieser Schritt nicht durchgeführt wird werden die Tage nach Alphabet geordnet
plot_data$weekday<- factor(plot_data$weekday, levels= c( "Montag",
"Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag","Sonntag"))
plot_data <- plot_data %>% arrange(weekday)
plot_ly(
x = plot_data$weekday,
y = plot_data$n,
name = "",
type = "bar"
)
setwd('C:\\Users\\Drecker\\Documents\\Lehre')
sen_train <- read.csv(file = ".\\Daten\\Sentiment\\Corona_NLP_train.csv")
sen_test <- read.csv(file = ".\\Daten\\Sentiment\\Corona_NLP_test.csv")
train_stat <- sen_train %>% group_by(Sentiment) %>%
summarise(Anzahl = n(), Anteil = n()/ sen_train %>% group_by(Sentiment) %>% count() %>% ungroup(Sentiment) %>% summarise('Other'=sum(n)))
train_stat
## # A tibble: 5 x 3
## Sentiment Anzahl Anteil$Other
## <chr> <int> <dbl>
## 1 Extremely Negative 5481 0.133
## 2 Extremely Positive 6624 0.161
## 3 Negative 9917 0.241
## 4 Neutral 7713 0.187
## 5 Positive 11422 0.278
test_stat <- sen_test %>% group_by(Sentiment) %>%
summarise(Anzahl = n(), Anteil = n()/ sen_test %>% group_by(Sentiment) %>% count() %>% ungroup(Sentiment) %>% summarise('Other'=sum(n)))
test_stat
## # A tibble: 5 x 3
## Sentiment Anzahl Anteil$Other
## <chr> <int> <dbl>
## 1 Extremely Negative 592 0.156
## 2 Extremely Positive 599 0.158
## 3 Negative 1041 0.274
## 4 Neutral 619 0.163
## 5 Positive 947 0.249
setwd('C:\\Users\\Drecker\\Documents\\Lehre')
fake <- read.csv(file = ".\\Daten\\Fakenews_detection\\Fake.csv")
true <- read.csv(file = ".\\Daten\\Fakenews_detection\\True.csv")
head(true[1])
## title
## 1 As U.S. budget fight looms, Republicans flip their fiscal script
## 2 U.S. military to accept transgender recruits on Monday: Pentagon
## 3 Senior U.S. Republican senator: 'Let Mr. Mueller do his job'
## 4 FBI Russia probe helped by Australian diplomat tip-off: NYT
## 5 Trump wants Postal Service to charge 'much more' for Amazon shipments
## 6 White House, Congress prepare for talks on spending, immigration